<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.3/css/all.min.css" integrity="sha256-2H3fkXt6FEmrReK448mDVGKb3WW2ZZw35gI7vqHOE4Y=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{&quot;hostname&quot;:&quot;www.nilstorm.com&quot;,&quot;root&quot;:&quot;&#x2F;&quot;,&quot;images&quot;:&quot;&#x2F;images&quot;,&quot;scheme&quot;:&quot;Gemini&quot;,&quot;version&quot;:&quot;8.5.0&quot;,&quot;exturl&quot;:false,&quot;sidebar&quot;:{&quot;position&quot;:&quot;left&quot;,&quot;display&quot;:&quot;post&quot;,&quot;padding&quot;:18,&quot;offset&quot;:12},&quot;copycode&quot;:false,&quot;bookmark&quot;:{&quot;enable&quot;:false,&quot;color&quot;:&quot;#222&quot;,&quot;save&quot;:&quot;auto&quot;},&quot;fancybox&quot;:false,&quot;mediumzoom&quot;:false,&quot;lazyload&quot;:false,&quot;pangu&quot;:false,&quot;comments&quot;:{&quot;style&quot;:&quot;tabs&quot;,&quot;active&quot;:null,&quot;storage&quot;:true,&quot;lazyload&quot;:false,&quot;nav&quot;:null},&quot;motion&quot;:{&quot;enable&quot;:true,&quot;async&quot;:false,&quot;transition&quot;:{&quot;post_block&quot;:&quot;fadeIn&quot;,&quot;post_header&quot;:&quot;fadeInDown&quot;,&quot;post_body&quot;:&quot;fadeInDown&quot;,&quot;coll_header&quot;:&quot;fadeInLeft&quot;,&quot;sidebar&quot;:&quot;fadeInUp&quot;}},&quot;prism&quot;:false,&quot;i18n&quot;:{&quot;placeholder&quot;:&quot;Searching...&quot;,&quot;empty&quot;:&quot;We didn&#39;t find any results for the search: ${query}&quot;,&quot;hits_time&quot;:&quot;${hits} results found in ${time} ms&quot;,&quot;hits&quot;:&quot;${hits} results found&quot;}}</script><script src="/js/config.js"></script>
<meta name="description" content="本文将介绍利用Bat指令以及Git等工具实现自动化拉取远程分支，同时使用gradle自动编译打包发送邮件到指定邮箱的过程，实现自动化编译与通知功能，因为当时的需求只有自动打包与通知，所以也没有加入异常处理机制，日志记录也不完善，但是整体思路是一致的，其余的是体验上的加强。">
<meta property="og:type" content="article">
<meta property="og:title" content="利用bat实现Android的自动化编译">
<meta property="og:url" content="http://www.nilstorm.com/2017/55efffcd.html">
<meta property="og:site_name" content="Lam&#39;s Blog">
<meta property="og:description" content="本文将介绍利用Bat指令以及Git等工具实现自动化拉取远程分支，同时使用gradle自动编译打包发送邮件到指定邮箱的过程，实现自动化编译与通知功能，因为当时的需求只有自动打包与通知，所以也没有加入异常处理机制，日志记录也不完善，但是整体思路是一致的，其余的是体验上的加强。">
<meta property="og:locale">
<meta property="og:image" content="https://tva1.sinaimg.cn/large/007S8ZIlgy1gee6wkfo69j30e9026gm4.jpg">
<meta property="article:published_time" content="2017-03-03T04:33:38.000Z">
<meta property="article:modified_time" content="2021-06-06T08:08:18.174Z">
<meta property="article:author" content="LinBinghe">
<meta property="article:tag" content="bat">
<meta property="article:tag" content="android">
<meta property="article:tag" content="自动化">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://tva1.sinaimg.cn/large/007S8ZIlgy1gee6wkfo69j30e9026gm4.jpg">


<link rel="canonical" href="http://www.nilstorm.com/2017/55efffcd.html">



<script class="next-config" data-name="page" type="application/json">{&quot;sidebar&quot;:&quot;&quot;,&quot;isHome&quot;:false,&quot;isPost&quot;:true,&quot;lang&quot;:&quot;zh-Hans&quot;,&quot;comments&quot;:true,&quot;permalink&quot;:&quot;http:&#x2F;&#x2F;www.nilstorm.com&#x2F;2017&#x2F;55efffcd.html&quot;,&quot;path&quot;:&quot;2017&#x2F;55efffcd.html&quot;,&quot;title&quot;:&quot;利用bat实现Android的自动化编译&quot;}</script>

<script class="next-config" data-name="calendar" type="application/json">&quot;&quot;</script>
<title>利用bat实现Android的自动化编译 | Lam's Blog</title>
  




  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<link rel="alternate" href="/atom.xml" title="Lam's Blog" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar" role="button">
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">Lam's Blog</h1>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">Knowledge as Action</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>







</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%89%8D%E8%A8%80"><span class="nav-number">1.</span> <span class="nav-text">前言</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="nav-number">2.</span> <span class="nav-text">配置文件</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E8%87%AA%E5%8A%A8%E7%BC%96%E8%AF%91bat%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9"><span class="nav-number">3.</span> <span class="nav-text">自动编译bat文件内容</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E7%BC%96%E8%AF%91%E5%90%8Ebat%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9"><span class="nav-number">4.</span> <span class="nav-text">编译后bat文件内容</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E6%80%BB%E7%BB%93"><span class="nav-number">5.</span> <span class="nav-text">总结</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="LinBinghe"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">LinBinghe</p>
  <div class="site-description" itemprop="description">Knowledge as Action</div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives">
          <span class="site-state-item-count">39</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
        <span class="site-state-item-count">13</span>
        <span class="site-state-item-name">categories</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
        <span class="site-state-item-count">60</span>
        <span class="site-state-item-name">tags</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author site-overview-item animated">
      <span class="links-of-author-item">
        <a href="https://github.com/LinBinghe" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;LinBinghe" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i></a>
      </span>
      <span class="links-of-author-item">
        <a href="https://www.zhihu.com/people/shawn_lam" title="Zhihu → https:&#x2F;&#x2F;www.zhihu.com&#x2F;people&#x2F;shawn_lam" rel="noopener" target="_blank"><i class="fab fa-zhihu fa-fw"></i></a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:linbinghe@gmail.com" title="E-Mail → mailto:linbinghe@gmail.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i></a>
      </span>
  </div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="Back to top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-Hans">
    <link itemprop="mainEntityOfPage" href="http://www.nilstorm.com/2017/55efffcd.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="LinBinghe">
      <meta itemprop="description" content="Knowledge as Action">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Lam's Blog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          利用bat实现Android的自动化编译
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">Posted on</span>

      <time title="Created: 2017-03-03 12:33:38" itemprop="dateCreated datePublished" datetime="2017-03-03T12:33:38+08:00">2017-03-03</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">Edited on</span>
        <time title="Modified: 2021-06-06 16:08:18" itemprop="dateModified" datetime="2021-06-06T16:08:18+08:00">2021-06-06</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">In</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/bat/" itemprop="url" rel="index"><span itemprop="name">bat</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <p>本文将介绍利用Bat指令以及Git等工具实现自动化拉取远程分支，同时使用gradle自动编译打包发送邮件到指定邮箱的过程，实现自动化编译与通知功能，因为当时的需求只有自动打包与通知，所以也没有加入异常处理机制，日志记录也不完善，但是整体思路是一致的，其余的是体验上的加强。<br><span id="more"></span></p>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>一些基础的东西这里将不作赘述，如git、gralde、bat指令等，以及过程中涉及的各个工具的环境搭建，这些都可以自行百度，资料非常多。</p>
<h1 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h1><p>为了使用上的便利，最好能提供给使用者自行配置具体项目具体参数的文件，毕竟不是所有人都了解bat，下面提供该编译工具配置所需要的git资源的样例：</p>
<p><pre><code>git邮箱|git密码|git地址|git分支|该分支具体某次提交记录（放空默认最新）|git项目名</code></pre><br>打包完成后邮件地址配置样例：</p>
<p><pre><code>
发件人邮箱  
发件人邮箱密码  
这是邮件标题  
这是具体邮件内容  
收件人1邮箱  
收件人2邮箱
</code></pre></p>
<h1 id="自动编译bat文件内容"><a href="#自动编译bat文件内容" class="headerlink" title="自动编译bat文件内容"></a>自动编译bat文件内容</h1><p>因为git内容比较多，所以具体的讲解我直接注释在代码里面，bat的注释以rem开头，其中一些重要命令也会稍加注释，如果有一些没有注释的又不清楚的可以百度了解一下。</p>
<p><pre><code><br>@echo off &amp; setlocal enabledelayedexpansion<br>COLOR 0A<br>:cloneBegin<br>rem <em>初始化参数.</em><br>set gitUser=””<br>set gitPwd=””<br>set gitUrl=””<br>set gitBranch=””<br>set gitCommit=””<br>set gitProjectName=””<br>set cloneStr=””<br>set /a index=0<br>set cloneRootPath=””<br>set cloneBranchPath=””<br>set cloneCommitPath=””<br>set currentGitName=””<br>set /a status=0<br>set /a mailIndex=0<br>rem <em>从git-config文件中逐行读取配置信息，并将项目及其依赖库拉去至本地.</em><br>for /f “tokens=1-6 delims==|” %%a in (git-config.txt) do (<br>    rem <em>初始化参数.</em><br>    set “gitUser=%%a”<br>    set “gitPwd=%%b”<br>    set “gitUrl=%%c”<br>    set “gitBranch=%%d”<br>    set “gitCommit=%%e”<br>    rem <em>转义@字符.</em><br>    set gitUser=!gitUser:@=%%40!<br>    set gitUrl=!gitUrl:<a target="_blank" rel="noopener" href="https://=!">https://=!</a><br>    set gitUrl=!gitUrl:<a target="_blank" rel="noopener" href="http://=!">http://=!</a><br>    rem <em>生成git clone的指令.</em><br>    set cloneStr=<a target="_blank" rel="noopener" href="http://!gitUser!:!gitPwd!@!gitUrl!">http://!gitUser!:!gitPwd!@!gitUrl!</a> -b !gitBranch!<br>    set “currentGitName=%%f”  </p>
<pre><code>echo !cloneStr!  

if !index! EQU 0 (  
    set &quot;gitProjectName=%%f&quot;  
    echo ***************!currentGitName! start clone...***************  
    rem *拉去主项目到当前目录下的项目名目录下.*  
    git clone !cloneStr! ./!gitProjectName!  
) else (  
    echo ***************!currentGitName! start clone...***************  
    cd !gitProjectName!  
    rem *拉去依赖项目到主项目目录下的依赖库名目录下.*  
    git clone !cloneStr! ./!currentGitName!  
    rem *dp0 表示当前该bat文件的目录下.*  
    cd %~dp0  
)  
rem *设置当前项目的build.gradle路径以及其分支名与提交记录路径.*  
if !index! EQU 0 (  
    set &quot;cloneRootPath=%~dp0!gitProjectName!\build.gradle&quot;  
    set &quot;cloneBranchPath=%~dp0!gitProjectName!\.git\HEAD&quot;  
    set &quot;cloneCommitPath=%~dp0!gitProjectName!\.git\refs\heads\!gitBranch!&quot;  
) else (  
    set &quot;cloneRootPath=%~dp0!gitProjectName!\%%f&quot;  
    set &quot;cloneBranchPath=%~dp0!gitProjectName!\%%f\.git\HEAD&quot;  
    set &quot;cloneCommitPath=%~dp0!gitProjectName!\%%f\.git\refs\heads\!gitBranch!&quot;  
)  
rem *判断当前项目是否拉取成功，其分支与当前所处提交记录是否正确*  
if exist !cloneRootPath! (  
    echo *******!currentGitName! clone complete...*******  
    find /i &quot;!gitBranch!&quot; !cloneBranchPath! &amp;&amp; (  
        echo *******!currentGitName! clone branch correctly...*******  
        if &quot;!gitCommit!&quot;==&quot; &quot; (  
            echo *******!currentGitName! clone latest commit correctly...*******  
        )||(  
            find /i &quot;!gitCommit!&quot; !cloneCommitPath! &amp;&amp; (  
                echo *******!currentGitName! clone seleteced commit correctly...*******  
            )||(  
                if !index! EQU 0 (  
                    cd %~dp0!gitProjectName!  
                ) else (  
                    cd %~dp0!gitProjectName!\!currentGitName!  
                )  
                rem *更改分支*  
                git reset --hard !gitCommit!  
                cd %~dp0  
                find /i &quot;!gitCommit!&quot; !cloneCommitPath! &amp;&amp; (  
                    echo *******!currentGitName! clone seleteced commit correctly...*******  
                )||(  
                    echo *******!currentGitName! clone seleteced commit failed...*******  
                    rem rd /s /q %~dp0!gitProjectName!  
                    goto cloneError  
                )  
            )  
        )  
    )||(  
        echo *******!currentGitName! clone branch failed...*******  
        rem rd /s /q %~dp0!gitProjectName!  
        goto cloneError  
    )  
 ) else (  
    echo *******!gitProjectName! clone failed, please try again...*******  
    rem rd /s /q %~dp0!gitProjectName!  
    goto cloneError  
 )  
 set /a index+=1  
</code></pre><p>)<br>rem <em>编译项目.</em><br>if exist !cloneRootPath! (<br>    cd !gitProjectName!<br>    :buildApk<br>    gradle assembleRelease<br>    rem <em>after call other batch such as gradle, turn echo off to make command disappear.</em><br>    @echo off &amp; setlocal enabledelayedexpansion<br>    rem <em>编译完成的后续处理bat文件.</em><br>    call build-after.bat<br>    PAUSE<br>) else (<br>    :cloneError<br>    rem <em>错误处理，打印当前的信息判断是否配置错误，修改错误的配置信息后按回车重新开始编译.</em><br>    echo <strong><em>*</em></strong>!gitProjectName! clone failed, there are your configs in !currentGitName! as follow:<strong><em>*</em></strong><br>    echo        <strong><em>*</em></strong>gitUser=!gitUser!<strong><em>*</em></strong><br>    echo        <strong><em>*</em></strong>gitPwd=!gitPwd!<strong><em>*</em></strong><br>    echo        <strong><em>*</em></strong>gitUrl=!gitUrl!<strong><em>*</em></strong><br>    echo        <strong><em>*</em></strong>gitBranch=!gitBranch!<strong><em>*</em></strong><br>    echo        <strong><em>*</em></strong>gitCommit=!gitCommit!<strong><em>*</em></strong><br>    echo        <strong><em>*</em></strong>repositoryName=!currentGitName!<strong><em>*</em></strong><br>    echo <strong><em>*</em></strong>please check for errors and correct them, press any key to reclone after all<strong><em>*</em></strong><br>    PAUSE<br>    goto :cloneBegin<br>)<br>PAUSE<br>&lt;/code&gt;&lt;/pre&gt;</p>
<h1 id="编译后bat文件内容"><a href="#编译后bat文件内容" class="headerlink" title="编译后bat文件内容"></a>编译后bat文件内容</h1><p>该文件在上一个bat文件末尾自动调用，也可在编译后直接运行，判断是否编译成功，若编译成功则调用blat工具发送邮件到指定给指定的收件人。</p>
<p><pre><code>
@echo off & setlocal enabledelayedexpansion   
set status=0  
set sendUser=""  
set sendPwd=""  
set mailTitle=""  
set mailContent=""  
set /a mailIndex=0  
cd %~dp0  
rem *从git-config文件中读取主项目名.*  
for /f "tokens=1-6 delims==|" %%a in (git-config.txt) do (  
    if !status! EQU 0 (  
        set status=1  
        rem *判断主项目名是否编译成功.*  
        if exist %~dp0%%f\app\build\outputs\apk\app-release.apk (  
            echo *******%%f build success*******  
            rem *生成当前时间.*  
            set time=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%  
            rem *重命名生成的apk文件，并将其移至指定目录.*  
            ren %~dp0%%f\app\build\outputs\apk\app-release.apk %%f_1.0.0_!time!.apk  
            move %~dp0%%f\app\build\outputs\apk\%%f_1.0.0_!time!.apk %~dp0  
            rd /s /q %~dp0%%f  
            rem *逐行读取邮件配置文件内容，最后调用blat发送邮件给每个收件人.*  
            for /f "" %%a in (mail-config.txt) do (  
                if !mailIndex! EQU 0 (  
                    set "sendUser=%%a"  
                )  
                if !mailIndex! EQU 1 (  
                    set "sendPwd=%%a"  
                )  
                if !mailIndex! EQU 2 (  
                    set "mailTitle=%%a"  
                )  
                if !mailIndex! EQU 3 (  
                    set "mailContent=%%a"  
                )  
                if !mailIndex! GTR 3 (  
                    blat -body "!mailContent!" -to %%a -s "!mailTitle!" -u !sendUser! -pw !sendPwd! -charset UTF-8  
                )  
                set /a mailIndex+=1  
            )  
        ) else (  
            echo *******%%f build failed*******  
            echo *******please check for errors and correct them, press any key to rebuild after all*******  
            PAUSE  
        )  
    )  
)  
PAUSE  
</code></pre></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>写这个自动化编译工具时自己对bat语言一无所知，gradle、blat这些工具也是边做边学，但是主要难度还是在于bat的编写上，有时候一条语句就要琢磨个半天，而且由于所花时间有限，写的工具只能算是勉强能用，若要谈到良好的体验那肯定是差之甚远，有兴趣的朋友可以自己拿去优化优化然后分享出来，也可以大家一起交流讨论。</p>
<hr>
<p><strong>版权声明</strong></p>
<p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gee6wkfo69j30e9026gm4.jpg" alt="Creative Commons BY-NC-ND 4.0 International License"></p>
<p><a target="_blank" rel="noopener" href="http://linbinghe.me/">Lam’s Blog</a> by <a target="_blank" rel="noopener" href="http://linbinghe.me/">Binghe Lin</a> is licensed under a <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons BY-NC-ND 4.0 International License</a>.<br>由<a target="_blank" rel="noopener" href="http://linbinghe.me/">林炳河</a>创作并维护的<a target="_blank" rel="noopener" href="http://linbinghe.me/">Lam’s Blog</a>采用<a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">创作共用保留署名-非商业-禁止演绎4.0国际许可证</a>。</p>
<p>本文首发于<a target="_blank" rel="noopener" href="http://linbinghe.me/">Lam’s Blog - Knowledeg as Action</a>，版权所有，侵权必究。</p>
<p>本文永久链接：<a target="_blank" rel="noopener" href="http://codinglife.me/2017/55efffcd.html">http://codinglife.me/2017/55efffcd.html</a></p>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/bat/" rel="tag"># bat</a>
              <a href="/tags/android/" rel="tag"># android</a>
              <a href="/tags/%E8%87%AA%E5%8A%A8%E5%8C%96/" rel="tag"># 自动化</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2017/e7f2af2c.html" rel="prev" title=" Android 应用层面屏蔽状态栏下拉方法总结">
                  <i class="fa fa-chevron-left"></i>  Android 应用层面屏蔽状态栏下拉方法总结
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/2017/3.698e+119.html" rel="next" title="关于Java单元测试，你需要知道的一切">
                  关于Java单元测试，你需要知道的一切 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">LinBinghe</span>
</div>
  <div class="powered-by">Powered by <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/" rel="noopener" target="_blank">NexT.Gemini</a>
  </div>

    </div>
  </footer>

  
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script>

  






  





</body>
</html>
